/*! ******************************************************************************
 *
 * Created on 2021年9月25日
 *
 * Copyright(c) YuZhou Big Data Laboratory CO.,Ltd, 2022.  All rights reserved.
 *
 *******************************************************************************
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with
 * the License. You may obtain a copy of the License at
 *
 *    http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 ******************************************************************************/

package org.yzbdl.lanius.core.plugins.service;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.apache.commons.lang.StringUtils;
import org.pentaho.di.core.plugins.PluginTypeInterface;
import org.yzbdl.lanius.core.event.EventContext;
import org.yzbdl.lanius.core.exception.LaniusEngineDbException;
import org.yzbdl.lanius.core.plugins.event.CategoryAddEvent;
import org.yzbdl.lanius.core.plugins.event.CategoryDeleteEvent;
import org.yzbdl.lanius.core.plugins.event.CategoryModifyEvent;
import org.yzbdl.lanius.core.plugins.metastore.*;

/**
 * 分组数据业务
 *
 * @author hs@yzbdl.ac.cn
 * @version 1.0
 * @date 2019-06-11 10:40
 */
public class CategoryService {

    private LdrCategoryDao ldrCategoryDao = LdrCategoryDao.getInstance();
    private LdrPluginCategoryDao ldrPluginCategoryDao = LdrPluginCategoryDao.getInstance();

    private static CategoryService categoryService = new CategoryService();

    private CategoryService() {}

    public static CategoryService getInstance() {
        return categoryService;
    }

    /**
     * 修改 CategoryEntity
     *
     * @param entity
     */
    public void modify(LdrCategoryEntity entity) {
        try {
            ldrCategoryDao.update(entity);
            EventContext.publish(new CategoryModifyEvent(entity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void updateCategoryNew(String description, String pluginTypeClass, Integer sortNum,
        Integer classficationId) {
        try {
            ldrCategoryDao.updateCategory(description, pluginTypeClass, sortNum, classficationId);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void updateCategoryName(Integer id, String newName) {
        try {
            LdrCategoryEntity one = ldrCategoryDao.getOne(id);
            ldrCategoryDao.update(id, newName);
            EventContext.publish(new CategoryDeleteEvent(one));
        } catch (LaniusEngineDbException e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除 CategoryEntity
     *
     * @param entity
     */
    public void delete(LdrCategoryEntity entity) {
        try {
            ldrCategoryDao.delete(entity.getId());
            EventContext.publish(new CategoryDeleteEvent(entity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 删除 CategoryEntity
     *
     * @param categoryEntityId 分组Id
     * @param classificationId 栏目Id
     */
    public void delete(String categoryEntityId, String classificationId) {
        try {
            LdrCategoryEntity one = ldrCategoryDao.getOne(Integer.parseInt(categoryEntityId));
            ldrCategoryDao.delete(Integer.parseInt(categoryEntityId));
            ldrPluginCategoryDao.delete(Integer.parseInt(categoryEntityId));
            EventContext.publish(new CategoryDeleteEvent(one));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public List<LdrPluginCategoryEntity> getAll(String categoryEntityId) {
        try {
            return ldrPluginCategoryDao.getAll(Integer.parseInt(categoryEntityId));
        } catch (LaniusEngineDbException e) {
            e.printStackTrace();
        }
        return null;
    }

    /**
     * 获取某个类别下面的所有分组
     *
     * @param classificationId 分类ID
     * @return
     */
    public List<LdrCategoryEntity> getAllByClassificationId(Integer classificationId) {
        try {
            return ldrCategoryDao.getAllByClassificationId(classificationId);
        } catch (Exception e) {
            e.printStackTrace();
            return new ArrayList<>();
        }
    }

    /**
     * 展开分组
     *
     * @param ids
     */
    public void expandCategory(Integer... ids) {
        try {
            ldrCategoryDao.updateExpandStatus(true, ids);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 收缩分组
     *
     * @param ids
     */
    public void collapseCategory(Integer... ids) {
        try {
            ldrCategoryDao.updateExpandStatus(false, ids);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    /**
     * 添加本地分类
     * <p>
     * 1,如果数据库已经存在, 则直接查询返回 <br/>
     * 2,如果数据库还没有记录, 则先新增再返回.
     *
     * @param ldrClassificationEntity 栏目实体
     * @param category 分组实体
     * @throws LaniusEngineDbException
     */
    public LdrCategoryEntity addLocalCategory(LdrClassificationEntity ldrClassificationEntity, String category)
        throws LaniusEngineDbException {
        LdrCategoryEntity ldrCategoryEntity = ldrCategoryDao.getOne(ldrClassificationEntity.getId(), category);
        if (ldrCategoryEntity == null) {
            ldrCategoryEntity = new LdrCategoryEntity();
            ldrCategoryEntity.setName(category);
            ldrCategoryEntity.setClassificationId(ldrClassificationEntity.getId());
            ldrCategoryEntity.setPluginTypeClass(ldrClassificationEntity.getPluginTypeClass());
            // categoryEntity.setFuncType(functype);
            ldrCategoryEntity = ldrCategoryDao.save(ldrCategoryEntity);
            EventContext.publish(new CategoryAddEvent(ldrCategoryEntity));
        }

        return ldrCategoryEntity;
    }

    public void addGroupItem(String name, Class<? extends PluginTypeInterface> pluginTypeClass, Integer parentId) {
        try {
            LdrCategoryEntity entity = new LdrCategoryEntity();
            entity.setName(name);
            // entity.setFuncType(funcType);
            entity.setClassificationId(parentId);
            entity.setPluginTypeClass(pluginTypeClass.getName());
            entity.setCreateTime(new Date());
            // entity.setExpanded();
            Integer sortNum = ldrCategoryDao.getCustomizeMaxSortNum(pluginTypeClass.getName(), parentId);
            sortNum = (sortNum == null ? 0 : sortNum);
            entity.setSortNum(sortNum + 1);

            ldrCategoryDao.save(entity);

            EventContext.publish(new CategoryAddEvent(entity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public void addGroupItem(String name, String pluginTypeClass, Integer parentId) {
        try {
            if (StringUtils.isEmpty(name))
                return;
            LdrCategoryEntity entity = new LdrCategoryEntity();
            entity.setName(name);
            // entity.setFuncType(funcType);
            entity.setClassificationId(parentId);
            entity.setPluginTypeClass(pluginTypeClass);
            entity.setCreateTime(new Date());
            // entity.setExpanded();
            Integer sortNum = ldrCategoryDao.getCustomizeMaxSortNum(pluginTypeClass, parentId);
            sortNum = (sortNum == null ? 0 : sortNum);
            entity.setSortNum(sortNum + 1);

            ldrCategoryDao.save(entity);

            EventContext.publish(new CategoryAddEvent(entity));
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    public LdrCategoryEntity getOne(Integer id) {
        try {
            return ldrCategoryDao.getOne(id);
        } catch (LaniusEngineDbException e) {
            return null;
        }
    }
}
